import { DataProxy } from "../../frame/A-LIB/lib.b.data";
import { AudioManager } from "../../frame/component/audio-manager";
import { APP_NAME } from "../../frame/frame.config";
import { NCAPIURI, NCBody } from "../api/api.config.client";
import ServiceAPI from "../api/service.api";
import get_proxy_status from "../data/data.status";
import get_proxy_trigger from "../data/data.trigger";
import get_proxy_user from "../data/data.user";
import { FORCE_POP } from "../game.config";
import Config from "./config.manager";
import GameAssets from "./game.assets";

export default class GameDC {
	private static _user_: ReturnType<typeof get_proxy_user>;
	private static _trigger_: ReturnType<typeof get_proxy_trigger>;
	private static _status_: ReturnType<typeof get_proxy_status>;

	public static get User(){
		return GameDC._user_;
	}
	public static get Trigger(){
		return GameDC._trigger_;
	}
	public static get Status(){
		return GameDC._status_;
	}

	private static __guide_inited__: mtec.NudityPromise<'end'>;
	public static get guideInited(){
		return GameDC.__guide_inited__.promise;
	}

	public static init(){
		GameDC._user_ = get_proxy_user('game_user', APP_NAME);
		GameDC._trigger_ = get_proxy_trigger('game_trigger');
		GameDC._status_ = get_proxy_status('game_status');

		GameDC.rank_list = mtec.local.read(APP_NAME + 'rank_list');

		GameDC.__guide_inited__ = new mtec.NudityPromise<'end'>();

		GameDC.listening();
	}

	public static listening(){

		DataProxy.follow(GameDC.User, 'bgm', (_, pick)=>{
			AudioManager.mute(!pick);
		}, false);

		if(GameDC.Status.guideInited){
			GameDC.__guide_inited__.resolve('end');
		}else{
			let reg = DataProxy.follow(GameDC.Status, 'guideInited', ()=>{
				DataProxy.cancel(reg);
				GameDC.__guide_inited__.resolve('end');
			}, false);
		}
	}

	public static checkTask(type: 'remove'|'round', id: number){
		return new RegExp('(?<!\\d)'+id+'(?!\\d)', 'gm').test(type=='round' ? GameDC.User.task_round : GameDC.User.task_remove);
	}

	public static recordTask(type: 'remove'|'round', id: number|string){
		let str = type=='round' ? GameDC.User.task_round : GameDC.User.task_remove;
		if(str!='') str += ';';
		if(type=='round') GameDC.User.task_round = str+id;
		else GameDC.User.task_remove = str+id;
	}

	private static rank_list: Array<{nickname: string, round: number, symbol: number, place: number}>;
	public static get RankList(){
		return GameDC.rank_list;
	}
	/** 初始化排行榜数据 */
	public static initRankData(
		name_list: string[],
		conf: {
			range100: [number, number];
			roundIncrease: [number, number];
			rangeCoe: [number, number];
		}
	){
		let list: Array<{nickname: string, round: number, symbol: number, place: number}> = [];

		list.push({
			nickname: mtec.array.random(name_list),
			round: mtec.number.random(...conf.range100, 0),
			symbol: 0,
			place: 0
		});

		list[0].symbol = list[0].round * mtec.number.random(...conf.rangeCoe, 0);

		while(list.length<100){
			list.unshift({nickname: mtec.array.random(name_list), round: 0, symbol: 0, place: 0});
			list[0].round = list[1].round + mtec.number.random(...conf.roundIncrease, 0);
			list[0].symbol = list[0].round * mtec.number.random(...conf.rangeCoe, 0);
		}

		GameDC.rank_list = list.sort((a, b)=>b.round - a.round);

		list.forEach((el, i)=>el.place = i+1);

		mtec.local.save(APP_NAME + 'rank_list', list);

		return list;
	}

	/** 检测并记录强弹 */
	public static checkForcePop(): NCBody<NCAPIURI.AD>['type']{
		let count = GameDC.User.remove_count;

		if(!(count>0) || count%3!=0) return void 0;

		let rp_count = Math.floor(count / 3);
		let conf = FORCE_POP.find(el=>rp_count.inRange(el.range[0], el.range[1]));

		let force_rp = (mtec.local.read<number>(APP_NAME+'force-rp') ?? 0) + 1;
		let force_idx = (mtec.local.read<number>(APP_NAME+'force-idx') ?? 0);


		if(conf.range[0] == rp_count) force_idx = 0;

		let force = force_rp >= conf.interval[force_idx];

		let type: NCBody<NCAPIURI.AD>['type'];
		if(force){
			force_idx = (force_idx + 1) % conf.interval.length;
			force_rp = 0;

			let force_count = (mtec.local.read<number>(APP_NAME+'force-count') ?? 0) + 1;
			if(force_count <= 5){
				type = 'full-screen';
				mtec.local.save(APP_NAME+'force-count', force_count);
			}else type = 'incentive';
		}

		mtec.local.save(APP_NAME+'force-rp', force_rp);
		mtec.local.save(APP_NAME+'force-idx', force_idx);

		return type;
	}

	private static live_comments_list: Array<{nickname: string, count: number, symbol: number, channel: string}> = [];
	/**
	 * 获取指定数量的弹幕
	 * @param count
	 */
	public static getLiveComments(count?: number){
		count = count ?? GameDC.live_comments_list.length;
		while(GameDC.live_comments_list.length < count) GameDC.live_comments_list.push(GameDC.createLiveComments(GameDC.User.round));
		return GameDC.live_comments_list.slice(0, count);
	}
	/**
	 * 根据指定的关卡，创建一条弹幕文本
	 * @param round
	 */
	private static createLiveComments(round: number){
		let nickname = GameAssets.getNickname();
		let count = round>=4 ? mtec.number.random(15, 30, 0) : 1;
		let symbol = 0;
		if(round>=4){
			let coe = mtec.number.random(...Config.officialConf.livecomments.fruit4CoeRange, 0);
			symbol = count * coe;
		}else{
			symbol = Reflect.get(Config.officialConf.livecomments, 'fruit'+round);
		}

		//hnc.log.tag('创建弹幕: green;' + [
		//	['关卡', round+1],
		//	['挑战次数', count],
		//	['金额', GameDC.symbolString(symbol)],
		//	['昵称', nickname],
		//].map(([a, b])=>a+':tan;'+b+':azure').join(';'));
		return {nickname, count, symbol, channel: mtec.array.random(Config.countryConf.channel)};
	}

	/**
	 * 从顶部丢弃指定数量的弹幕数据
	 * @param count
	 */
	public static throwAwayLiveComments(count?: number){

		let new_list = mtec.array.create(GameDC.live_comments_list.splice(0, count??1).length, ()=>GameDC.createLiveComments(GameDC.User.round));

		GameDC.live_comments_list.push(...new_list);
	}

	public static checkGuideID(id: number){
		let reg = new RegExp('(?<!\\d)'+id+'(?!\\d)', 'gm');
		return reg.test(GameDC.User.guide_record);
	}

	public static DoneGuideID(id: number){
		if(GameDC.checkGuideID(id)){
			return void 0;
		}

		if(GameDC.User.guide_record==''){
			GameDC.User.guide_record += id;
		}else{
			GameDC.User.guide_record += ':'+id;
		}
	}

	public static CleanGuideID(...list: number[]){
		if(list.length>0){
			let guid_done = GameDC.User.guide_record;
			list.forEach(id=>{
				let reg = new RegExp('(?<!\\d)'+id+'(?!\\d)', 'gm');
				guid_done = guid_done.replace(reg, '');
			});
			GameDC.User.guide_record = guid_done.replaceAll(/(?<!\d):/gm, '').replaceAll(/:(?!\d)/gm, '');
		}
	}

	private static __prop_geted__: Array<`${'shuffle'|'stash'|'revoke'}-${'video'|'diamond'}`> = [];
	/** 当前获取道具的来源记录 */
	public static get prop_geted(){
		return GameDC.__prop_geted__;
	}

	private static _free_pool_: Awaited<ReturnType<typeof ServiceAPI.userInfo>>['freePool'] = [];
	public static get FreePool(){
		return GameDC._free_pool_;
	}
}